﻿using Common.Contract.Authentication.Record;
using Common.Contract.Paging;
using Common.Contract.ProductHandbook.Record;
using Common.Contract.ProductHandbook.Request;
using Common.Contract.ProductHandbook.Response;
using Common.Contract.SystemConfig.Record;
using Common.Service.Command;
using CrossSelling.Model.Interface;
using CrossSelling.Model.Model;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace CrossSelling.Core.ServiceCommand
{
    public class RetrieveChecklistDocumentByProductServiceCommand : ProviderServiceCommand<IProviderFactory, RetrieveChecklistDocumentByProductRequest, RetrieveChecklistDocumentByProductResponse>
    {
        #region Properties
        public UserRecord Dao;
        public FilterRecord TextSearch;
        public int pageSize = 10, pageIndex = 0, totalRecord = 0;
        public int Product;
        public int SubProductId;
        public List<int> ListHideDoc = new List<int>();
        #endregion
        public RetrieveChecklistDocumentByProductServiceCommand(IProviderFactory providers) : base(providers) { }
        protected override void Validate(RetrieveChecklistDocumentByProductRequest request)
        {
            if (request == null) throw new ArgumentNullException("request");
            if (!request.Header.ApplicationKey.HasValue || request.Header.ApplicationKey == Guid.Empty)
            {
                throw new ArgumentException("ApplicationKey must be set", "request");
            }
            if (string.IsNullOrEmpty(request.ProductId))
            {
                throw new ArgumentException("Product must be set", "request");
            }
            else
            {
                Int32.TryParse(request.ProductId, out Product);
            }

            if (request.CurrentUser == null)
            {
                throw new ArgumentException("MSBO Dao must be set", "request");
            }
            else
            {
                Dao = Request.CurrentUser;
            }
            TextSearch = Request.Filter;
            if (Request.Page != null)
            {
                pageIndex = Request.Page.PageIndex ?? 0;
                pageSize = Request.Page.PageSize ?? 0;
            }
        }

        protected override bool OnExecute(RetrieveChecklistDocumentByProductResponse response)
        {
            bool isSuccess = true;
            string errorMessage = string.Empty;
            try
            {
                List<ChecklistDocumentRecord> records = new List<ChecklistDocumentRecord>();

                List<CheckListDocument> listCustomer = new List<CheckListDocument>();
                if (!string.IsNullOrEmpty(Request.QuestionData))
                {
                    int SubProductId = GetSubProductNameByQuestion(Request.QuestionData);
                    listCustomer = Providers.ProductHandbooks.RetrieveListDocumentChecklist(out totalRecord, Product, SubProductId, Dao, TextSearch, Request.Lang, pageSize, pageIndex);

                    response.SubProductName = Providers.ProductHandbooks.RetrieveSubProductById(SubProductId).SubProductName;

                    if (listCustomer != null)
                    {
                        records = listCustomer.Where(x => !ListHideDoc.Contains(x.ChecklistDocId)).Select(x => new ChecklistDocumentRecord
                        {
                            DocumentGroup = x.DocumentGroup,
                            DocumentGroupCategory = x.DocumentGroupCategory,
                            isCheck = false,
                            Document = x.Document,
                            Original = x.Original,
                            Copy = x.Copy,
                            Duplicate = x.Duplicate,
                            Note = x.Note,
                            PictureDoc = x.PictureDocument,
                            Id = x.ChecklistDocId.ToString(),
                            SubProductId = x.SubProductId
                        }).ToList();
                    }

                }
                else if (!string.IsNullOrEmpty(Request.SubProductId))
                {
                    ChecklistSubProduct SubProduct = Providers.ProductHandbooks.RetrieveSubProductById(int.Parse(Request.SubProductId));
                    listCustomer = Providers.ProductHandbooks.RetrieveListDocumentChecklist(out totalRecord, Product, SubProduct.SubProductId, Dao, TextSearch, Request.Lang, pageSize, pageIndex);

                    response.SubProductName = SubProduct.SubProductName;

                    if (listCustomer != null)
                    {
                        records = listCustomer.Select(x => new ChecklistDocumentRecord
                        {
                            DocumentGroup = x.DocumentGroup,
                            DocumentGroupCategory = x.DocumentGroupCategory,
                            Document = x.Document,
                            Original = x.Original,
                            Copy = x.Copy,
                            Duplicate = x.Duplicate,
                            Note = x.Note,
                            PictureDoc = x.PictureDocument,
                            Id = x.ChecklistDocId.ToString(),
                            SubProductId = x.SubProductId
                        }).ToList();
                    }
                }

                response.Records = records;
                response.Page = new PageRecord
                {
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    TotalRecords = totalRecord
                };
            }
            catch (Exception e)
            {
                isSuccess = false;
                errorMessage = e.Message;
            }

            response.ErrorMessage = errorMessage;
            return isSuccess;
        }

        private int GetSubProductNameByQuestion(string data)
        {
            int result = 0;
            List<string> listQuestionAnwser = data.Split('^').ToList();
            List<ChecklistQuestionSubProductResult> listChecklists = new List<ChecklistQuestionSubProductResult>();
            listQuestionAnwser.ForEach(x =>
            {
                var item = x.Split('=');
                listChecklists.Add(new ChecklistQuestionSubProductResult
                {
                    QuestionId = int.Parse(item[0].Split('_')[1].ToString()),
                    Answer = item[1]
                });
            });


            Dictionary<int, ChecklistQuestionSubProductResult> dicChecklist = listChecklists.ToDictionary(x => x.QuestionId);

            List<ChecklistQuestionSubProductResult> listChecklistSample = Providers.ProductHandbooks.RetrieveListChecklistSample(Product);

            List<ChecklistCheck> checkSample = listChecklistSample.GroupBy(x => x.SubProductId).Select(group => new ChecklistCheck
            {
                Count = group.Count(),
                SubProductId = group.Key,
                listResult = group.ToList()
            }).ToList();

            checkSample.ForEach(x =>
            {
                bool isProduct = x.Count == x.listResult.Count(y => dicChecklist.ContainsKey(y.QuestionId) && dicChecklist[y.QuestionId].Answer == y.Answer);
                if (isProduct == true)
                {
                    result = x.SubProductId;
                }
            });
            if (result == 0)
            {
                result = Providers.ProductHandbooks.RetrieveSubProductWithoutSubId(Product, checkSample.FirstOrDefault().SubProductId).FirstOrDefault().SubProductId;
            }
            List<ChecklistHideDocWhenAnswer> listHideDoc = Providers.ProductHandbooks.RetrieveListDocHide(result);

            listHideDoc.Where(x => dicChecklist.ContainsKey(x.QuestionId) && dicChecklist[x.QuestionId].Answer == x.Answer).ToList().ForEach(y =>
            {
                y.DocumentId.Split(',').ToList().ForEach(z => ListHideDoc.Add(int.Parse(z)));
            });
            return result;
        }

        private class ChecklistCheck
        {
            public int Count { get; set; }
            public int SubProductId { get; set; }
            public List<ChecklistQuestionSubProductResult> listResult { get; set; }
        }
    }
}
